package com.ruoyi.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.business.bo.HcxMerchantTypeAddBo;
import com.ruoyi.business.bo.HcxMerchantTypeEditBo;
import com.ruoyi.business.bo.HcxMerchantTypeQueryBo;
import com.ruoyi.business.mapper.HcxMerchantTypeMapper;
import com.ruoyi.business.service.IHcxMerchantTypeService;
import com.ruoyi.business.vo.HcxMerchantTypeVo;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.HcxMerchantType;
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.AssertUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商家分类Service业务层处理
 *
 * @author wsdz
 * @date 2022-08-17
 */
@Service
public class HcxMerchantTypeServiceImpl extends ServicePlusImpl<HcxMerchantTypeMapper, HcxMerchantType> implements IHcxMerchantTypeService {

    @Override
    public List<HcxMerchantType> selectMerchantTypetList(HcxMerchantType type) {
        return baseMapper.selectMerchantTypeList(type);
    }

    @Override
    public HcxMerchantTypeVo queryById(Long id) {
        return getVoById(id, HcxMerchantTypeVo.class);
    }


    @Override
    public List<HcxMerchantTypeVo> queryList(HcxMerchantTypeQueryBo bo) {
        return listVo(buildQueryWrapper(bo), HcxMerchantTypeVo.class);
    }

    private LambdaQueryWrapper<HcxMerchantType> buildQueryWrapper(HcxMerchantTypeQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HcxMerchantType> lqw = Wrappers.lambdaQuery();
        lqw.like(StrUtil.isNotBlank(bo.getName()), HcxMerchantType::getName, bo.getName());
        lqw.eq(bo.getParentId() != null, HcxMerchantType::getParentId, bo.getParentId());
        lqw.eq(bo.getOrderSort() != null, HcxMerchantType::getOrderSort, bo.getOrderSort());
        lqw.eq(StrUtil.isNotBlank(bo.getDelFlag()), HcxMerchantType::getDelFlag, bo.getDelFlag());
        return lqw;
    }

    @Override
    public Boolean insertByAddBo(HcxMerchantTypeAddBo bo) {
        HcxMerchantType add = BeanUtil.toBean(bo, HcxMerchantType.class);
        validEntityBeforeSave(add);
      //  HcxMerchantType info = getById(bo.getParentId());
      //  add.setAncestors(info.getAncestors() + ',' + bo.getParentId());
        return save(add);
    }

    @Override
    public Boolean updateByEditBo(HcxMerchantTypeEditBo bo) {
        HcxMerchantType update = BeanUtil.toBean(bo, HcxMerchantType.class);
        validEntityBeforeSave(update);
        return updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(HcxMerchantType entity) {
        // 判断商品分类是否存在
        HcxMerchantType hcxMerchantType = getOne(new LambdaQueryWrapper<HcxMerchantType>()
                .eq(HcxMerchantType::getName, entity.getName())
                .eq(HcxMerchantType::getParentId, entity.getParentId())
                .last("limit 1")
        );
        // 如果是新增操作
        if (ObjectUtil.isEmpty(entity.getId())) {
            AssertUtils.isTrue(ObjectUtil.isEmpty(hcxMerchantType), "新增商品分类" + entity.getName() + ",失败，商品分类名称已存在");
        } else {
            if (ObjectUtil.isNotEmpty(hcxMerchantType) && entity.getId().longValue() != hcxMerchantType.getId().longValue()) {
                throw new CustomException("修改商品分类" + entity.getName() + ",失败，商品分类名称已存在");
            } else if (entity.getId().equals(entity.getParentId())) {
                throw new CustomException("修改商品分类" + entity.getName() + ",失败，上级分类不能选择自己");
            }
        }
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }

    @Override
    public String importHcxMerchantType(List<HcxMerchantTypeVo> hcxMerchantTypeList) {
        AssertUtils.isTrue(CollectionUtils.isNotEmpty(hcxMerchantTypeList), "导入数据不能为空");
        int successNum = 0;
        for (HcxMerchantTypeVo hcxMerchantType : hcxMerchantTypeList) {
            HcxMerchantType add = BeanUtil.toBean(hcxMerchantType, HcxMerchantType.class);
            save(add);
            successNum++;
        }
        String msg = String.format("导入完成，共计 %d 条数据，成功 %d 条！", hcxMerchantTypeList.size(), successNum);
        if (successNum != hcxMerchantTypeList.size()) {
            msg = msg + String.format("失败 %d 条！", hcxMerchantTypeList.size() - successNum);
        }
        return msg;
    }

    @Override
    public List<TreeSelect> buildMerchantTypeTreeSelect(List<HcxMerchantType> merchantTypes) {
        List<HcxMerchantType> deptTrees = buildMerchantTypeTree(merchantTypes);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 构建前端所需要树结构
     */
    @Override
    public List<HcxMerchantType> buildMerchantTypeTree(List<HcxMerchantType> merchantTypes) {
        List<HcxMerchantType> returnList = new ArrayList<>();
        List<Long> tempList = new ArrayList<>();
        for (HcxMerchantType dept : merchantTypes) {
            tempList.add(dept.getId());
        }
        for (HcxMerchantType dept : merchantTypes) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(merchantTypes, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty()) {
            returnList = merchantTypes;
        }
        return returnList;
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<HcxMerchantType> list, HcxMerchantType t) {
        // 得到子节点列表
        List<HcxMerchantType> childList = getChildList(list, t);
        t.setChildren(childList);
        for (HcxMerchantType tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<HcxMerchantType> getChildList(List<HcxMerchantType> list, HcxMerchantType t) {
        List<HcxMerchantType> tlist = new ArrayList<>();
        for (HcxMerchantType n : list) {
            if (Validator.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }


    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<HcxMerchantType> list, HcxMerchantType t) {
        return getChildList(list, t).size() > 0;
    }
}
